package cn.iocoder.yudao.module.distm.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.distm.dal.dataobject.schedule.ScheduleRecordDO;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * project : hangshiServer
 * <p> 解析航班日志 </p>
 *
 * @author yisl
 * @date 2025-07-19【星期六】
 **/
@Slf4j
public class FlightLogUtils {
    private static final Pattern basicPattert = Pattern.compile(
            "(\\w+)\\s+/?(\\d{2}[A-Z]{3})\\s+\\S+\\s+" +  // 航班号和日期
                    "(\\S+)\\s+" +                                 // 机型
                    ".*?(\\d{4})",                                 // 起飞时间
            Pattern.DOTALL);
    // 匹配所有舱位餐食信息 (J/W/Y/C/P/G)
    private static final Pattern pattern = Pattern.compile(
            "([JYWCGP])(\\d+(?:/.*?\\d+)*).*?(?:\\s+\\S\\s+(\\d{4}))?",
            Pattern.DOTALL);

    // 匹配特殊餐食 (多种格式)
    private static final Pattern specialPattern = Pattern.compile(
            "^\\s*1[A-Z]{3}L\\s+.*$",
            Pattern.MULTILINE);

    public static void extractFlightMealData(String input, ScheduleRecordDO  data) {

        // 1. 提取航班基本信息
        extractBasicInfo(input, data);

        // 2. 提取舱位餐食信息
        extractMealClasses(input, data);

        // 3. 提取特殊餐食
        extractSpecialMeals(input, data);

    }

    private static void extractBasicInfo(String input, ScheduleRecordDO data) {

        Matcher matcher = basicPattert.matcher(input);
        if (matcher.find()) {
            data.setFlightNo(matcher.group(1)) ;
            data.setRecordDate(parseFlightDate(matcher.group(2)));
            data.setAircraftType(matcher.group(3));
            data.setDepTime(parseDepTime(matcher.group(4)));
        }
    }

    private static void extractMealClasses(String input, ScheduleRecordDO data) {

        Matcher matcher = pattern.matcher(input);
        while (matcher.find()) {
            String classType = matcher.group(1);
            String mealCount = matcher.group(2);

            switch (classType) {
                case "J":
                case "C":
                    if (ObjectUtil.isEmpty(data.getBussClassQty())) {
                        data.setBussClassQty(0);
                    }
                    data.setBussClassQty(data.getBussClassQty()+parseQty(mealCount));
                    break;
                case "P":
                case "Y":
                    if (ObjectUtil.isEmpty(data.getEcoClassQty())) {
                        data.setEcoClassQty(0);
                    }
                    data.setEcoClassQty(data.getEcoClassQty()+parseQty(mealCount));
                    break;
                case "W":
                case "G":
                    if (ObjectUtil.isEmpty(data.getPremEcoClassQty())) {
                        data.setPremEcoClassQty(0);
                    }
                    data.setPremEcoClassQty(data.getPremEcoClassQty()+parseQty(mealCount)); // 处理C舱(商务)和G舱(超级经济舱)
                    break;
            }
        }
    }

    private static void extractSpecialMeals(String input, ScheduleRecordDO data) {
        StringBuilder sb = new StringBuilder();

        Matcher matcher = specialPattern.matcher(input);
        while (matcher.find()) {
            sb.append(matcher.group()).append(" ").append("\n");
        }
        data.setSpecialRemarks(sb.toString());
    }


    /**
     * 将航班日期字符串(如19MAY)转换为LocalDate对象
     * @param dateStr 航班日期字符串(格式: ddMMM)
     * @return 对应的LocalDate对象(默认使用当前年份)
     * @throws DateTimeParseException 如果字符串格式不正确
     */
    private static LocalDate parseFlightDate(String dateStr) {
        try {
            // 创建格式化器，指定英文月份缩写格式
            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                    .parseCaseInsensitive()
                    .parseDefaulting(ChronoField.YEAR, Year.now().getValue())
                    .appendPattern("ddMMM")
                    .toFormatter(Locale.ENGLISH);

            // 解析日期字符串(自动使用当前年份)
            return LocalDate.parse(dateStr, formatter);
        } catch (DateTimeParseException e) {
            log.error("日期格式不正确: " + e.getMessage());
        }

        return null;
    }

    /**
     * 将当前日期转成ddMMM
     * @return 对应的ddMMM字符串
     */
    public static String formatFlightDate() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMM", Locale.ENGLISH);
        return LocalDate.now().format(formatter).toUpperCase();
    }

    /**
     * 将预计起飞时间字符串(如)转换为LocalTime对象
     * @param dateStr 航班日期字符串(格式: hhmm)
     * @return 对应的LocalDate对象(默认使用当前年份)
     * @throws DateTimeParseException 如果字符串格式不正确
     */
    private static LocalTime parseDepTime(String dateStr) {
        try {
            if (ObjectUtil.isEmpty(dateStr) || dateStr.trim().length() != 4) {
                return null;
            }
            dateStr = dateStr.trim();
            dateStr = dateStr.substring(0, 2) + ":" + dateStr.substring(2);
            // 解析日期字符串(自动使用当前年份)
            return LocalTime.parse(dateStr, DateTimeFormatter.ofPattern("HH:mm"));
        } catch (DateTimeParseException e) {
            log.error("日期格式不正确: " + e.getMessage());
        }

        return null;
    }

    /**
     * 将客户数量字符串(如)转换为Integer对象
     * @param dateStr 客户数量(格式: 5//5，5)
     * @return 对应的数量
     * @throws DateTimeParseException 如果字符串格式不正确
     */
    private static Integer parseQty(String dateStr) {

        if (ObjectUtil.isNotEmpty(dateStr)){
            dateStr = dateStr.trim();
            String[] split = dateStr.split("//|/");
            if (split.length == 2) {
                int qty1 = Integer.parseInt(split[0]);
                int qty2 = split[1].matches("(?s).*[a-zA-Z].*")?0:Integer.parseInt(split[1]);
                return Math.max(qty1, qty2);
            }
            if (split.length == 3) {
                int qty1 = Integer.parseInt(split[0]);
                int qty2 = split[1].matches(".*[a-zA-Z].*")?0:Integer.parseInt(split[1]);
                int qty3 = split[2].matches(".*[a-zA-Z].*")?0:Integer.parseInt(split[2]);
                return Math.max(qty3, Math.max(qty1, qty2));
            }
            return Integer.parseInt(split[0]);
        }
        return 0;
    }
}
